//==============================================================================
//
//               Copyright (C) 2005  Dick van Oudheusden
//  
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this program; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//==============================================================================
// 
//  $Date: 2005-06-27 17:15:19 $ $Revision: 1.1 $
//
//==============================================================================

#include <stdlib.h>
#include <math.h>

#include "ofc/DValue.h"
#include "ofc/DFraction.h"

#include "DInc.h"
#include "DTest.h"


//-DataType--------------------------------------------------------------------

void DValue_test(void)
{
  DValue     *value     = [DValue new];
  DFraction  *fraction  = [DFraction new];
  DFraction  *cpy       = nil;
  DBool      *bvalue    = nil;
  DInt       *ivalue    = nil;
  DLong      *lvalue    = nil;
  DDouble    *dvalue    = nil;
  DText      *svalue    = nil;
  
  STARTTEST();

  TEST([value isEmpty]);
  TEST([value type] == DVL_EMPTY);
  TEST(strcmp([value typeString], "empty") == 0);

  
  // Class value
  [value setClass :[DFraction class]];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_CLASS);
  TEST(strcmp([value typeString], "DFraction") == 0);
  TEST( [value getClass] == [DFraction class]);
  
  TEST([value toClass] == [DFraction class]);
  cpy = [value toObject];
  TEST([cpy class] == [DFraction class]);
  [cpy free];
  TEST([value toSel] == NULL);
  TEST([value toBool] == NO);
  TEST([value toInt] == 0);
  TEST([value toLong] == 0);
  TEST([value toDouble] == 0.0);
  TEST([value toText] == nil);
  
    
  // Object reference value
  [fraction set :1 :10];
  
  [value setObject :fraction];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_OBJECT);
  TEST(strcmp([value typeString], "DFraction") == 0);
  TEST( [value getObject] == fraction);
  
  TEST([value toClass] == [DFraction class]);

  cpy = [value toObject];
  TEST(cpy != nil);
  TEST(cpy != fraction);
  TEST([cpy compare :fraction] == 0);
  [cpy free];

  TEST([value toSel] == NULL);
  TEST([value toBool] == NO);
  TEST([value toInt] == 0);
  TEST([value toLong] == 0);
  TEST(fabs([value toDouble] - 0.1) < 0.01);
  TEST([[value toText] ccompare :"1/10"] == 0);
  
  
  // Selector value
  [value setSel :@selector(clear)];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_SEL);
  TEST(strcmp([value typeString], "selector") == 0);
  TEST( [value getSel] == @selector(clear));
  
  TEST([value toClass] == Nil);
  TEST([value toObject] == nil);
  TEST([value toSel] == @selector(clear));
  TEST([value toBool] == NO);
  TEST([value toInt] == 0);
  TEST([value toLong] == 0);
  TEST([value toDouble] == 0.0);
  TEST([value toText] == nil);

  
  // Boolean value
  [value setBool :YES];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_BOOL);
  TEST(strcmp([value typeString], "bool") == 0);
  TEST( [value getBool] == YES);
  
  TEST([value toClass] == Nil);
  bvalue = [value toObject];
  TEST([bvalue class] == [DBool class]);
  TEST([bvalue get] == YES);
  [bvalue free];
  TEST([value toSel] == NULL);
  TEST([value toBool] == YES);
  TEST([value toInt] == 1);
  TEST([value toLong] == 1);
  TEST([value toDouble] == 1.0);
  TEST([[value toText] icompare :"YES"] == 0);
  
  
  // Integer value
  [value setInt :-432];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_INT);
  TEST(strcmp([value typeString], "int") == 0);
  TEST( [value getInt] == -432);
  
  TEST([value toClass] == Nil);
  ivalue = [value toObject];
  TEST([ivalue class] == [DInt class]);
  TEST([ivalue get] == -432);
  [ivalue free];
  TEST([value toSel] == NULL);
  TEST([value toBool] == YES);
  TEST([value toInt] == -432);
  TEST([value toLong] == -432);
  TEST([value toDouble] == -432.0);
  TEST([[value toText] icompare :"-432"] == 0);

  
  // Integer value
  [value setLong :132000];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_LONG);
  TEST(strcmp([value typeString], "long") == 0);
  TEST( [value getLong] == 132000);
  
  TEST([value toClass] == Nil);
  lvalue = [value toObject];
  TEST([lvalue class] == [DLong class]);
  TEST([lvalue get] == 132000);
  [lvalue free];
  TEST([value toSel] == NULL);
  TEST([value toBool] == YES);
  TEST([value toInt] == 132000);
  TEST([value toLong] == 132000);
  TEST([value toDouble] == 132000.0);
  TEST([[value toText] icompare :"132000"] == 0);

  
  // Double value
  [value setDouble :3.141592];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_DOUBLE);
  TEST(strcmp([value typeString], "double") == 0);
  TEST( [value getDouble] == 3.141592);
  
  TEST([value toClass] == Nil);
  dvalue = [value toObject];
  TEST([dvalue class] == [DDouble class]);
  TEST([dvalue get] == 3.141592);
  [lvalue free];
  TEST([value toSel] == NULL);
  TEST([value toBool] == YES);
  TEST([value toInt] == 3);
  TEST([value toLong] == 3);
  TEST([value toDouble] == 3.141592);
  TEST([[value toText] icompare :"3.14159"] == 0);

  
  // String value
  [value setString :"yes, i'm here"];
  
  TEST(![value isEmpty]);
  TEST( [value type] == DVL_STRING);
  TEST(strcmp([value typeString], "string") == 0);
  TEST(strcmp([value getString], "yes, i'm here") == 0);
  
  TEST([value toClass] == Nil);
  svalue = [value toObject];
  TEST([svalue class] == [DText class]);
  TEST([svalue ccompare :"yes, i'm here"] == 0);
  [svalue free];
  TEST([value toSel] == NULL);
  TEST([value toBool] == YES); // yes, i..
  TEST([value toInt] == 0);
  TEST([value toLong] == 0);
  TEST([value toDouble] == 0.0);
  svalue = [value toText];
  TEST([svalue ccompare :"yes, i'm here"] == 0);
  [svalue free];
  
  [value free];

  STOPTEST();
}

